package com.copa.module.order.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.copa.constant.OrderStatusConstant;
import com.copa.domain.ResponseDto;
import com.copa.module.cart.domain.entity.CartEntity;
import com.copa.module.cart.service.CartService;
import com.copa.module.cart.service.GoodsManage;
import com.copa.module.goods.domain.dto.GoodsInfoDto;
import com.copa.module.goods.service.GoodsService;
import com.copa.module.order.domain.dto.OrderDetailDto;
import com.copa.module.order.domain.dto.OrderGoodsDetailDto;
import com.copa.module.order.domain.dto.OrderListDto;
import com.copa.module.order.domain.entity.OrderEntity;
import com.copa.module.order.domain.entity.OrderGoodsEntity;
import com.copa.module.order.domain.entity.OrderLogEntity;
import com.copa.module.order.domain.vo.OrderAddVo;
import com.copa.module.order.domain.vo.OrderRefundVo;
import com.copa.module.order.mapper.OrderDao;
import com.copa.module.order.service.OrderGoodsService;
import com.copa.module.order.service.OrderLogService;
import com.copa.module.order.service.OrderService;
import com.copa.module.user.manage.UserRoleManage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.copa.constant.OrderStatusConstant.PARTREFUND;
import static com.copa.constant.SubOrderStatusConstant.APPLYREFUND;
import static com.copa.constant.SubOrderStatusConstant.NORMAL;

/**
 * @author copa
 * @createDate 2021-01-25 12:00
 * @function
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private CartService cartService;

    @Autowired
    private GoodsManage goodsManage;

    @Autowired
    private UserRoleManage userRoleManage;

    @Autowired
    private OrderGoodsService orderGoodsService;

    @Autowired
    private OrderLogService orderLogService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto<String> post(OrderAddVo orderAddVo, String openId) {
        Long userId = userRoleManage.getUserByOpenId(openId).getData().getId();
        // 购物车删除
        ResponseDto<String> cardDeleteRes = cartService.deleteList(userId, orderAddVo.getCartIds());
        if (cardDeleteRes.isNotSuccess()) {
            return ResponseDto.errorMsg(cardDeleteRes.getMsg());
        }

        // 订单增加
        List<CartEntity> cartList = cartService.findList(userId, orderAddVo.getCartIds());
        BigDecimal goodsPrice = goodsManage.calTotalMoney(orderAddVo.getCartIds());
        orderAddVo.setGoodsPrice(goodsPrice);
        Long insertOrder = orderDao.insertOrder(orderAddVo, userId);
        if (insertOrder == 0) {
            return ResponseDto.errorMsg("系统繁忙，请稍后再下单！");
        }
        Long orderId = orderDao.selectLastOrderId(userId);

        // 子订单添加
        List<OrderGoodsEntity> orderGoodsEntities = Lists.newLinkedList();
        // 子订单编号处理
        int number = 1 ;
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setMinimumIntegerDigits(3);
        numberFormat.setGroupingUsed(false);
        for (CartEntity cart : cartList) {
            OrderGoodsEntity orderGoods = new OrderGoodsEntity();
            orderGoods.setOrderId(orderId)
                    .setOrderGoodsSn(orderAddVo.getOrderSn() + numberFormat.format(number))
                    .setProductId(cart.getProductId())
                    .setPrice(goodsManage.findGoodsSpuByProductId(cart.getProductId()).getPrice())
                    .setNum(cart.getNum());
            orderGoodsEntities.add(orderGoods);
            number++;
        }
        ResponseDto<Boolean> orderGoodAddFlag = orderGoodsService.addOrderGoods(orderGoodsEntities);
        if (orderGoodAddFlag.isNotSuccess()) {
            return ResponseDto.errorMsg(orderGoodAddFlag.getMsg());
        }
        // 添加日志
        OrderLogEntity orderLog = OrderLogEntity.builder()
                .message("下单成功，请前往支付")
                .orderId(orderAddVo.getOrderSn())
                .orderStatus(OrderStatusConstant.WAITPAY.getOrderStatus())
                .build();
        orderLogService.addOrderLog(orderLog);
        return ResponseDto.success(orderAddVo.getOrderSn());
    }

    @Override
    public ResponseDto<List<OrderListDto>> list(Long orderStatus, String openId) {
        Long userId = userRoleManage.getUserByOpenId(openId).getData().getId();
        List<OrderListDto> orderDtoList = orderDao.list(orderStatus, userId);
        if (ObjectUtil.isNotNull(orderDtoList) && ObjectUtil.length(orderDtoList) > 0) {
            // 处理规格
            orderDtoList.forEach(orderDto -> {
                List<GoodsInfoDto> goodsInfoDtoList = orderDto.getGoodsInfoDtoList();
                goodsInfoDtoList.forEach(goodsInfoDto -> {
                    List<String> spus = Lists.newArrayList();
                    String[] split = goodsInfoDto.getProductName().split(",");
                    for (String s : split) {
                        spus.add(s.substring(s.indexOf(":") + 1));
                    }
                    goodsInfoDto.setProductName(String.join("  ", spus));
                });
            });
            return ResponseDto.success(orderDtoList);
        }
        return ResponseDto.errorMsg("没有查到订单哦~");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto<String> cancel(Long orderId, String openId) {
        Long userId = userRoleManage.getUserByOpenId(openId).getData().getId();
        Map<String, Object> selectCondition = Maps.newHashMap();
        selectCondition.put("user_id", userId);
        selectCondition.put("id", orderId);
        List<OrderEntity> orderEntities = orderDao.selectByMap(selectCondition);
        if (ObjectUtil.isNull(orderEntities.get(0))) {
            return ResponseDto.errorMsg("查找不到该订单修改！");
        }
        OrderEntity order = orderEntities.get(0);
        if (!OrderStatusConstant.WAITPAY.getOrderStatus().equals(order.getOrderStatus())) {
            return ResponseDto.errorMsg("该订单不能取消！");
        }
        order.setOrderStatus(OrderStatusConstant.USERCANCEL.getOrderStatus());
        int update = orderDao.updateById(order);
        if (update > 0) {
            OrderLogEntity orderLog = OrderLogEntity.builder()
                    .message("取消订单")
                    .orderId(order.getOrderSn())
                    .orderStatus(OrderStatusConstant.USERCANCEL.getOrderStatus())
                    .build();
            orderLogService.addOrderLog(orderLog);
            return ResponseDto.success("取消订单成功！");
        }
        return ResponseDto.errorMsg("系统繁忙，请稍后再试！");
    }

    @Override
    public ResponseDto<OrderDetailDto> detail(Long orderId, String openId) {
        Long userId = userRoleManage.getUserByOpenId(openId).getData().getId();
        OrderDetailDto order = orderDao.findOrderDetailByOrderId(orderId, userId);
        if (ObjectUtil.isNotNull(order)) {


            List<OrderGoodsDetailDto> orderGoodsDetailDtoList = order.getOrderGoodsDetailDtoList();
            orderGoodsDetailDtoList.forEach(goodsInfoDto -> {
                // 处理规格
                List<String> spus = Lists.newArrayList();
                String[] split = goodsInfoDto.getProductName().split(",");
                for (String s : split) {
                    spus.add(s.substring(s.indexOf(":") + 1));
                }
                goodsInfoDto.setProductName(String.join("  ", spus));
                // 退款日志
                goodsInfoDto.setOrderLogDtoList(orderDao.selectOrderLogByOrderGoodsSn(goodsInfoDto.getOrderGoodsSn()));
            });
            return ResponseDto.success(order);
        }
        return ResponseDto.errorMsg("没有查到该订单的详情哦~");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto<String> applyRefund(OrderRefundVo orderRefundVo, String openId) {
        Long userId = userRoleManage.getUserByOpenId(openId).getData().getId();
        // 查询总订单
        Map<String, Object> selectCondition = Maps.newHashMap();
        selectCondition.put("order_sn", orderRefundVo.getOrderSn());
        selectCondition.put("user_id", userId);
        List<OrderEntity> orderEntities = orderDao.selectByMap(selectCondition);
        if (ObjectUtil.isNull(orderEntities.get(0))) {
            return ResponseDto.errorMsg("该订单不能退款！请联系商家！");
        }
        OrderEntity order = orderEntities.get(0);
        // 查询子订单
        selectCondition = Maps.newHashMap();
        selectCondition.put("order_id", orderEntities.get(0).getId());
        selectCondition.put("order_goods_sn", orderRefundVo.getOrderGoodsSn());
        ResponseDto<OrderGoodsEntity> orderGoodsRes =orderGoodsService.findOrderGoodsByMap(selectCondition);
        if (orderGoodsRes.isNotSuccess()) {
            return ResponseDto.errorMsg(orderGoodsRes.getMsg());
        }
        OrderGoodsEntity orderGoods = orderGoodsRes.getData();

        // 修改总订单状态
        if (!PARTREFUND.getOrderStatus().equals(order.getOrderStatus())) {
            order.setOrderStatus(PARTREFUND.getOrderStatus());
            orderDao.updateById(order);
        }

        // 修改子订单状态
        if (!NORMAL.getOrderStatus().equals(orderGoods.getRefundStatus())) {
            return ResponseDto.errorMsg("此订单不能申请退款！");
        }
        orderGoods.setRefundStatus(APPLYREFUND.getOrderStatus());
        ResponseDto<Boolean> updateOrderGoods = orderGoodsService.updateByOrderGoods(orderGoods);
        if (updateOrderGoods.isNotSuccess()) {
            return ResponseDto.errorMsg(updateOrderGoods.getMsg());
        }

        // 添加日志
        OrderLogEntity orderLog = OrderLogEntity.builder()
                .orderId(orderRefundVo.getOrderSn())
                .orderGoodsId(orderRefundVo.getOrderGoodsSn())
                .orderStatus(PARTREFUND.getOrderStatus())
                .subOrderStatus(APPLYREFUND.getOrderStatus())
                .message("申请退款，退款理由为【" + orderRefundVo.getRemark() != null ? orderRefundVo.getRemark() : "" + "】")
                .build();
        orderLogService.addOrderLog(orderLog);
        return ResponseDto.success();
    }
}
